/* Copyright (c) 2007 Nordic Semiconductor. All Rights Reserved.
 *
 * The information contained herein is property of Nordic Semiconductor ASA.
 * Terms and conditions of usage are described in detail in NORDIC
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 
 *
 * Licensees are granted free, non-transferable use of the information. NO
 * WARRENTY of ANY KIND is provided. This heading must NOT be removed from
 * the file.
 *
 * $LastChangedRevision: 2290 $
 */ 

/** @file
 *
 * Wireless Desktop Protocol interface for the host (dongle).
 *
 * @author Lasse Olsen
 *
 * @addtogroup nordic_protocol_wdp Wireless Desktop Protocol
 * @{
 */
 
#ifndef WDP_HOST_H__
#define WDP_HOST_H__

#include <stdint.h>
#include "wdp_common.h"

/**
Definition of address byte 0 for the different device types. 
The master address, byte 1-4, is generated randomly on pairing 
request or set by the application.
*/
typedef enum
{
  WDP_MOUSE_ADR_B0 = 0x38,
  WDP_KEYBOARD_ADR_B0,
  WDP_REMOTE_ADR_B0
} adr_byte0_def_t; 

#define WDP_DEVICE_SUPPORT_SIZE 3  

/**
Bit definition for input byte to function wdp_rx_setup().    
*/
#define WDP_LP_RX_BIT FAP_LP_RX_BIT
 
typedef enum
{
  WDP_RX_OFF = 0,
  WDP_RX_NORMAL = ((1 << WDP_REMOTE) | (1 << WDP_KEYBOARD) | (1 << WDP_MOUSE)),
  WDP_RX_PAIRING = (1 << WDP_PAIRING_PIPE),
  WDP_RX_SUSPEND = ((1 << WDP_LP_RX_BIT) | (1 << WDP_REMOTE) | (1 << WDP_KEYBOARD) | (1 << WDP_MOUSE))    
} wdp_rx_setup_t;

/** @name Host application functions */
//@{

/**
Initialization function for the Wireless Desktop Protocol (WDP). This function
must be called at least once before any of the remaining WDP functions may be used.

It is recommended that the timer interrupt service routine used by the WDP is not 
enabled until after the WDP is initialized.
*/
void wdp_host_init(void);

/**
Function for setting up the receiver. 

The protocol offers two different receive modes; one @b low @b latency mode and one 
@b low @b power mode to be used during normal operation and USB suspend, respectively. 

@param setup specifies (indirectly) which addresses/frequencies to be monitored.

@arg @c WDP_RX_NORMAL monitors all device addresses/frequencies using low latency receive mode. 
Pairing will be disabled.

@arg @c WDP_RX_SUSPEND monitors all device addresses/frequencies using low power receive mode. 
Pairing will be disabled.

@arg @c WDP_RX_PAIRING enables pairing by monitoring the global pairing address/frequencies. 
During pairing normal device user data reception is disabled and the low latency receive mode is used. 

@arg @c WDP_RX_OFF shuts down the receiver.

*/
void wdp_host_rx_setup(wdp_rx_setup_t setup);

/**
Function for finding whether any pairing requests were received during the previous period that pairing
was enabled. Pairing is enabled using the function wdp_rx_setup(). This WDP  pairing status 
is cleared whenever any of the functions wdp_host_get_clear_pairing_result() 
or wdp_host_rx_setup() is called.
   
@return
@retval true if a no pairing requests received.
@retval false if one or more pairing requests were received during the last pairing enable session.

@sa wdp_host_rx_setup()
*/
bool wdp_host_get_clear_pairing_result(void);

/**
Function for getting the device master address. The master address is unique for each host and is the address 
that is distributed on pairing requests from devices. The master address is either randomly selected 
during the first received pairing request from a device or set explicitly using the function
wdp_host_set_master_adr(). The function wdp_host_get_master_adr() is typically 
used for reading out the randomly generated master address for EEPROM storage. After power up 
the function wdp_host_set_master_adr() can be used in order to recover this master address so
that devices do not need to re-pair when already paired. 

@param adr [out] is the pointer to where the 4 byte master address shall be written. 

@sa wdp_host_set_master_adr(), wdp_host_get_clear_pairing_result(), wdp_host_rx_setup(),
wdp_host_enable_random_adr_gen();   
*/
void wdp_host_get_master_adr(uint8_t *adr);

/**
Function for setting the master address for the host. This is the unique master address which 
is distributed on pairing requests from devices. The master address may either be randomly 
selected during a received pairing request from a device or set explicitly using this 
function. Using this function will automatically stop the random address generation.

This function is typically used for writing a master address stored in EEPROM so that previous 
paired devices not have to re-pair to the host after every host power disconnect.

@sa wdp_host_get_master_adr(), wdp_host_get_clear_pairing_result(), wdp_host_enable_random_adr_gen(),
wdp_host_rx_setup() 
*/
bool wdp_host_set_master_adr(uint8_t *adr);

/**
Function for clearing the master address and restart the random address generator. Calling this
function enables random generation of the master address to be distributed on the next pairing request. 
Any previous address specified using the function wdp_host_set_master_adr() will be discarded.
The random address generation is immediately halted if a new pairing request is received from a
device. Note that the function wdp_host_process_events() must be continuously called during 
address generation.  

@sa wdp_host_set_master_adr(), wdp_host_get_master_adr(), wdp_host_get_clear_pairing_result(), 
wdp_host_rx_setup(), wdp_host_process_events() 
 
*/
void wdp_host_enable_random_adr_gen(void);

/**
Function for processing WDP events. WDP events may be either a nRF radio 
interrupt or a WDP timer interrupt. 

This function processes any data received in the internal RX FIFO and does one of the following:

- Rejects the received data in case of invalid TYPE_ID.
- Handles the pairing response in case of a received pairing request.
- Forwards USER DATA to be available for the application.

This function should be called continuously in the main() loop of the program as it polls 
the receive FIFO for new receive data and increases a random counter from which 
the master address is fetched during pairing.

@return
@retval false if no radio activity
@retval true random data received (not necessarily application user data though)  

*/
bool wdp_host_process_events(void); 

/**
Function for reading received user data forwarded from 
wdp_host_process_events(). Note that this function should be called whenever
host_process_events() returns @b true in order to check if new application data
were received. Else unread application data may be overwritten on the next call
to wdp_process_events().  

@param dst [out] is the pointer to where the received data shall be copied. The
receive destination must be able to accommodate #WDP_MAX_PL_LENGTH number of
bytes. The exact number of bytes copied depends on the device type from which
the data was received. The payload data size and contents for the different 
device types are specified in wdp_common.h.

@return 
Returns the origin of the received data.

@retval 0 if no data were received.
@retval WDP_MOUSE if data received from a mouse. 
@retval WDP_KEYBOARD if data received from a keyboard. 
@retval WDP_REMOTE if data received from a remote control. 
*/
bool wdp_host_get_rx_data(uint8_t *dat, uint8_t* length, wdp_dev_types_t* origin);

/**
Function for writing downlink (host to device transmission) data for a given device. 

Downlink data transmission is always initiated by a data transmission from a device. 
This function only prepares the data to be piggybacked to the acknowledge packet returned on 
the next data packet received from the given device. 
Thus, an actual data transfer is not started when calling this function. 
The downlink data is transmitted on any data package received from the specified device type. 

Up to 3 downlink payloads may be preloaded.

@param dev_type specifies the downlink destination. 
@arg @c WDP_MOUSE (equals 1) writes downlink data for a mouse.
@arg @c WDP_KEYBOARD(equals 2) writes downlink data for a keyboard.
@arg @c WDP_REMOTE(equals 3) writes downlink data for a remote control.

@param length specifies the number of bytes to be written. Note that this number should not
exceed the constant #WDP_MAX_DL_PL_LENGTH defined in wdp_common.h. 

@param src [in] is a pointer to the data to be to copied to the downlink buffer. 

@param length specifies the number of bytes to be copied to downlink buffer.

@return
@retval false if downlink buffer full, thus >3 payloads previously written without being fetched by a device.

@retval true if payload successfully written to downlink buffer.

*/
bool wdp_host_write_downlink_data(wdp_dev_types_t dev_type, uint8_t *src, uint8_t length);

/**
Function for getting the connection status for a given device. 

The WDP contains functionality for setting up a continuous "keep alive" data link 
from a device to host. This function may be used to monitor the validity of this connection.

@param dev_type specifies the device for which to get the connection status. 
@arg @c WDP_MOUSE (equals 1) gets the mouse connection status.
@arg @c WDP_KEYBOARD(equals 2) gets the keyboard connection status.
@arg @c WDP_REMOTE(equals 3) gets the remote control connection status.

@return
Returns the connection status.
@retval true if the device is connected.
@retval false if the device is disconnected. 
*/
bool wdp_host_get_connection_status(wdp_dev_types_t dev_type);
//@}
/** @} */
#endif

